package com.bookstore.dao;

import com.bookstore.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class BaseDao<T> {
    private QueryRunner runner=new QueryRunner();
    private Class<T> type;
    public BaseDao() {
        // 获取父类的类型，这里的this是子类对象
        // getGenericSuperclass()：用来获取当前类的父类的类型，如果是带泛型的，
        // 则返回的type对象必须准确反映泛型参数的实际类型
        Type type1 = this.getClass().getGenericSuperclass();
        // ParameterizedType：表示参数化类型
        ParameterizedType superclass = (ParameterizedType) type1;//获取可变参数
        // 获取父类的泛型参数
        Type[] actualTypeArguments = superclass.getActualTypeArguments();
        // 获取第一个泛型参数，这里我们只用了一个泛型
        type=(Class<T>)actualTypeArguments[0];//取出可变参数类型
    }

    /**
     * 单条数据查询
     * @param sql
     * @param params
     * @return
     */
    public  T query(String sql,Object...params){
        Connection conn = null;
        T t= null;
        try {
            conn= DruidUtils.getConnection();
            t=runner.query(conn,sql,new BeanHandler<>(type),params);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DruidUtils.close(conn);
        }
        return t;
    }

    /**
     * 多条数据查询
     * @param sql
     * @return
     */
    public List<T> queryList(String sql){
        Connection conn = DruidUtils.getConnection();
        List<T> query=null;
        try {
            query = runner.query(conn, sql, new BeanListHandler<>(type));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        DruidUtils.close(conn);
        return query;
    }

    /**
     * 数据的增删改查
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object...params){
        Connection conn = DruidUtils.getConnection();
        int update = 0;
        try {
            update = runner.update(conn,sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DruidUtils.close(conn);
        }
        return update;
    }
}
